package math2;

import java.util.ArrayList;

/**
 * A basis for polynomials of degree p where the basis functions are Lagrange
 * functions up to order p.
 * 
 * @author hbui
 */
public class LagrangeFB extends PolynomialBasisOnRnToR {
	private int p;

	/**
	 * Constructs a Lagrange basis of degree 2.
	 */
	public LagrangeFB() {
		setP(2);
	}

	/**
	 * Constructs a Lagrange basis of degree p.
	 */
	public LagrangeFB(int p) {
		setP(p);
	}

	@Override
	public void setP(int p) {
		this.p = p;
		this.basis = createBasis(p);
	}

	@Override
	public int getP() {
		return this.p;
	}

	private ArrayList<FunctionRnToR> createBasis(int p) {
		double[] x = new double[p + 1];
		for (int i = 0; i < p + 1; i++) {
			x[i] = -1 + (2.0 * i / p);
		}
		PolynomialRToR[] s = new PolynomialRToR[p + 1];
		for (int i = 0; i < p + 1; i++) {
			int a = (i + 1) % (p + 1);
			s[a] = new PolynomialRToR(1);
			for (int j = 0; j < p + 1; j++) {
				if (i != j) {
					double[] c = new double[] { -x[j] / (x[i] - x[j]), 1 / (x[i] - x[j]) };
					PolynomialRToR sub = new PolynomialRToR(c);
					s[a] = (PolynomialRToR) s[a].multiply(1, sub);
				}

			}
		}
		PolynomialRToR temp = s[1];
		s[1] = s[0];
		s[0] = temp;

		ArrayList<FunctionRnToR> basis = new ArrayList<FunctionRnToR>();
		for (int i = 0; i < s.length; i++) {
			basis.add(s[i]);
		}
		return basis;
	}

	@Override
	public String toString() {
		return "Lagrange";
	}

	@Override
	public Object clone() {
		return new LagrangeFB(p);
	}
}
